#pragma once
#include <unistd.h>
#include <unordered_map>
#include "util.hpp"
#include "login.hpp"

class Server
{
public:
    Server() {}
    ~Server() {}
public:
    void readData(int sock)
    {
        // 读取数据
        char buf[NUM] = { 0 };
        int n = read(sock, buf, NUM);
        if (n <= 0)
        {
            return;
        }
        // 序列化数据
        Json::Reader reader;
        Json::Value root;
        reader.parse(buf, root);
        if (!root["passwd"].isNull())
        {
            Login l;
            bool result = l.registerOrLogin(root);
            if (result)
            {
                insertSock(root["user"].asString(), sock);
            }
            else
            {
                // 断开连接
                close(sock);
            }
            l.sendData(sock, result);
        }
        else if (!root["msg"].isNull() && !root["group"].isNull())
        {
            handleGroupMsg(sock, root["msg"].asString());
        }
        else if (!root["msg"].isNull())
        {
            handleMsg(sock, root["name"].asString(), root["msg"].asString());
        }
        else if (!root["group"].isNull())
        {
            handleGroupRequest();
        }
        else
        {
            handleRequest(sock, root["name"].asString());
        }
    }

    // 处理消息请求
    void handleMsg(int sock, const std::string& name, const std::string& msg)
    {
        // 将信息发送给对方
        Json::Value root;
        Json::StyledWriter writer;
        root["name"] = sockUser[sock];
        root["msg"] = msg;
        std::string data = writer.write(root);
        sendData(userSock[name], data);
    }

    // 处理群聊消息
    void handleGroupMsg(int sock, const std::string& msg)
    {
        std::cout << "处理群聊消息" << std::endl;
        Json::Value root;
        Json::StyledWriter writer;
        root["name"] = sockUser[sock];
        root["msg"] = msg;
        std::string data = writer.write(root);
        for (int i = 0;i < socks.size();i++)
        {
            if (socks[i] != sock)
            {
                sendData(socks[i], data);
            }
        }
    }

    // 处理聊天请求
    void handleRequest(int sock, const std::string& name)
    {
        Json::Value ret;
        Json::StyledWriter writer;
        bool ret1 = Util::findUser(name);
        bool ret2 = userSock.find(name) != userSock.end();
        if (ret1 && ret2)
        {
            // 发送请求, 将自己的用户名发送给对方
            ret["name"] = sockUser[sock];
            std::string data = writer.write(ret);
            sendData(userSock[name], data);
            Json::Value val;
            val["name"] = name;
            data = writer.write(val);
            sendData(sock, data);
        }
        else
        {
            std::cout << "该用户不存在或未不在线" << std::endl;
            ret["result"] = false;
            ret["name"] = name;
            std::string data = writer.write(ret);
            sendData(sock, data);
        }
    }

    void handleGroupRequest()
    {
        Json::Value root;
        Json::StyledWriter writer;
        for (auto e : userSock)
        {
            socks.push_back(e.second);
        }
        root["name"] = "搞笑份子";
        root["group"] = true;
        std::string data = writer.write(root);
        for (int i = 0;i < socks.size();i++)
        {
            sendData(socks[i], data);
        }
    }

    // 发送数据
    void sendData(int sock, const std::string& data)
    {
        write(sock, data.c_str(), data.length());
    }

    // 用户上线，将用户名与sock进行映射
    void insertSock(const std::string& user, const int sock)
    {
        userSock.insert({user, sock});
        sockUser.insert({sock, user});
        // 打印映射表
        for (auto& e : userSock)
        {
            std::cout << e.first << ", " << e.second << std::endl;
        }
        std::cout << std::endl;
    }

    // 用户离线，去除用户名与sock的映射
    void delSock(const std::string& user, int sock)
    {
        userSock.erase(user);
        sockUser.erase(sock);
    }
private:
    static std::unordered_map<std::string, int> userSock;
    static std::unordered_map<int, std::string> sockUser;
    static std::vector<int> socks;
};

std::unordered_map<std::string, int> Server::userSock;
std::unordered_map<int, std::string> Server::sockUser;
std::vector<int> Server::socks;